/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.base;

import picounit.features.base.exception.CorruptedClassFile;
import picounit.features.base.exception.MissingOrCorruptJar;

import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

class Jar implements Code {
	private final JarFile jarFile;

	public Jar(String fileName) {
		this.jarFile = createJarFile(fileName);
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Code methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	public byte[] findClass(String className) {
		byte[] byteCode = null;

		try {
			JarEntry jarEntry = jarEntry(className);

			if (jarEntry != null) {
				InputStream inputStream = jarFile.getInputStream(jarEntry);

				if (inputStream != null) {
					byteCode = new byte[(int) jarEntry.getSize()];

					inputStream.read(byteCode, 0, byteCode.length);
				}
			}

			return byteCode;
		}
		catch (IOException ioException) {
			throw new CorruptedClassFile(ioException);
		}
	}

	public InputStream openFile(String fileName) throws IOException {
		JarEntry jarEntry = jarFile.getJarEntry(fileName);

		return jarEntry == null ? null : jarFile.getInputStream(jarEntry);
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Object methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	@Override
	public String toString() {
		return "Jar: " + jarFile.getName();
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation
	///////////////////////////////////////////////////////////////////////////////////////////////

	private JarEntry jarEntry(String className) {
		return jarFile.getJarEntry(className.replace('.', '/') + ".class");
	}

	private static JarFile createJarFile(String fileName) {
		try {
			return new JarFile(fileName);
		}
		catch (IOException ioException) {
			throw new MissingOrCorruptJar(ioException);
		}
	}
}
